package com.damai.action.json;

import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.util.Map;

import com.citywithincity.api.entities.Customer;
import com.citywithincity.utils.ClassUtil;
import com.citywithincity.utils.StringUtils;
import com.damai.annotation.ParamGetter;
import com.damai.annotation.ParamValidate;
import com.damai.error.ApiError;
import com.damai.param.IParamValidate;
import com.damai.param.Rules;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;

class BeanJsonParamGetter implements IParamGetter {
	private Schema<?> schema;
	private Field[] fields;
	private String[] requireMessages;
	private IParamValidate[] validates;
	private IParamGetter[] getters;
	public BeanJsonParamGetter(Class<?> type) throws IntrospectionException {
		this.schema = RuntimeSchema.getSchema(type);
		fields = ClassUtil.getFields(type);
		requireMessages = new String[fields.length];
		validates = new IParamValidate[fields.length];
		getters = new IParamGetter[fields.length];
		int index = 0;
		for (Field field : fields) {
			field.setAccessible(true);
			ParamValidate validate = field.getAnnotation(ParamValidate.class);
			if(validate!=null){
				requireMessages[index]=StringUtils.isEmpty(validate.requireMessage()) ? null :validate.requireMessage();
				if(validate.rule().length>0){
					validates[index] = Rules.getValidate(validate.rule(),validate.message());
				}
				
			}
			ParamGetter paramGetter = field.getAnnotation(ParamGetter.class);
			if(paramGetter!=null){
				Class<?> getterClass = paramGetter.getter();
				String name = paramGetter.name();
				if(StringUtils.isEmpty(name)){
					name = field.getName();
				}
				try {
					getters[index]=(IParamGetter) ClassUtil.newInstance(getterClass, new Object[]{name});
				} catch (Exception e) {
					throw new RuntimeException("初始化getter " + getterClass.getName() +"失败");
				}
			}
			++index;
		}
	}

	@Override
	public Object get(Map<String, Object> param) {
		try {
			final Field[] fields = this.fields;
			final Schema<?> type = this.schema;
			final int count = fields.length;
			final String[] requireMessages = this.requireMessages;
			final IParamValidate[] validates = this.validates;
			
			Object obj = type.newMessage(); // 创建 JavaBean 对象
			// 给 JavaBean 对象的属性赋值
			for(int i=0 ; i < count; ++i){
				Field field = fields[i];
				String propertyName = field.getName();
				// 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。
				Object value;
				IParamGetter getter = getters[i];
				if(getter!=null){
					value = getter.get(param);
				}else{
					value = param.get(propertyName);
				}
				if(value == null){
					String requireMessage = requireMessages[i];
					if(requireMessage!=null){
						throw new ApiError(requireMessage);
					}else{
						continue;
					}
				}
				IParamValidate paramValidate = validates[i];
				if(paramValidate!=null){
					paramValidate.validateParam(value);
				}
				
				field.set(obj, value);
			}
			if(obj instanceof IUserData){
				Customer customer = (Customer) param.get("customer");
				if(customer!=null){
					((IUserData)obj).setUserId(customer.getId());
				}
				
			}
			
			return obj;
		} catch (Exception e) {
//			throw new ApiError("参数错误"+e.getMessage());
			throw new ApiError(e.getMessage());
		}
	}

}
